package com.penglecode.netty3.example1;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelHandler;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class EchoClient {

	private static final Logger logger = LoggerFactory.getLogger(EchoClient.class);
	
	public static void main(String[] args) throws Exception {
		
		ChannelFactory channelFactory = new NioClientSocketChannelFactory(
				Executors.newCachedThreadPool(),
				Executors.newCachedThreadPool());
		
		// Client服务启动器
		ClientBootstrap bootstrap = new ClientBootstrap(channelFactory);
		bootstrap.setOption("connectTimeoutMillis", 3000);
		// 客户端事件处理器
		final ChannelHandler clientHandler = new EchoClientHandler();
		
		// 设置一个处理服务端消息和各种消息事件的类(Handler)
		bootstrap.setPipelineFactory(new ChannelPipelineFactory(){
			public ChannelPipeline getPipeline() throws Exception {
				return Channels.pipeline(clientHandler);
			}
		});
		ChannelFuture channelFuture = bootstrap.connect(new InetSocketAddress(InetAddress.getLocalHost(), 9000));
		channelFuture.awaitUninterruptibly(); //以为是异步的,所以要等待服务器端的响应
		if(channelFuture.isCancelled()){
			logger.warn("Connection attempt cancelled by user!");
		}else if(!channelFuture.isSuccess()){
			logger.warn("Connection established failure!", channelFuture.getCause());
		}
		//获取channel关闭时被唤醒的ChannelFuture  
        //无论future是否成功都会返回CloseFuture，失败的时候会自动关闭Channel
		channelFuture.getChannel().getCloseFuture().awaitUninterruptibly(); //如果handler中不手动调用channel.close()那么此处在getCloseFuture()处等待
		channelFactory.releaseExternalResources(); // 可以看下源码,此句代码等效于bootstrap.shutdown()
	}

}
